﻿//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------

using Cinemachine;
using GameFramework;
using System;
using UnityEngine;
using UnityGameFramework.Runtime;

namespace Adventure
{
    public class PlayerEntity : FigureObject
    {
        private Rigidbody2D rb;
        private Animator anim;
        public InteractionCheck interactionCheck;

        private Vector2 inputDirection;
        private int  FaceDirection
        {
            get
            {
                if (inputDirection.x<0)
                {
                    return -1;
                }
                else if(inputDirection.x > 0)
                {
                    return 1;
                }
                return 0; 
            }
        }
  
        [Range(1, 6)]
        public float moveSpeed;
        [Range(1, 5)]
        public float jumpForce;


        private float animMovement;

        public bool animJump, animFall, animAttack, animHit, animDeath;
        public GameObject areaAttack01, areaAttack02;

        public PlayerEntityData playerEntityData;

        public ControllerForm controllerForm;
        protected override void OnInit(object userData)
        {
            base.OnInit(userData);
            gameObject.SetLayerRecursively(Constant.Layer.PlayerId);

            rb = GetComponent<Rigidbody2D>();
            anim = GetComponent<Animator>();
            interactionCheck = transform.FindTransform<InteractionCheck>("Interaction");

            areaAttack01 = transform.FindTransform<Transform>("AreaAttack01").gameObject;
            areaAttack02 = transform.FindTransform<Transform>("AreaAttack02").gameObject;

            moveSpeed = 3f;
            jumpForce = 1.4f;

        }
   
        protected override void OnShow(object userData)
        {
            base.OnShow(userData);

            if (userData!=null)
            {
                playerEntityData = (PlayerEntityData)userData;
            }
            GameEntry.InputComponent.MoveAction += InputDirection;
            GameEntry.InputComponent.JumpkAction += Jump;
            GameEntry.InputComponent.AttackAction += AttackFun;

            SetCameraLookPoint();

            areaAttack01.SetActive(false);
            areaAttack02.SetActive(false);

            int ControllerFormSerialId=GameEntry.DataNode.GetData<VarInt32>(Constant.ControllerFormSerialId);
            controllerForm =GameEntry.UI.GetUIForm(ControllerFormSerialId).GetComponent<ControllerForm>();

        }

        protected override void OnHide(bool isShutdown, object userData)
        {
            base.OnHide(isShutdown, userData);

            GameEntry.InputComponent.MoveAction -= InputDirection;
            GameEntry.InputComponent.JumpkAction -= Jump;
            GameEntry.InputComponent.AttackAction -= AttackFun;

            GameEntry.TimerComponent.CancelInvoke();
        }
        protected override void OnUpdate(float elapseSeconds, float realElapseSeconds)
        {
            base.OnUpdate(elapseSeconds, realElapseSeconds);
       
            SetAnimation();
        }

        private void FixedUpdate()
        {
            if (animHit) return;
         
            Movement();
        }

        private bool once;
        private void OnTriggerEnter2D(Collider2D collision)
        {
            if (collision.tag=="Gold"&&once==false)
            {
                //加金币

                GameEntry.Sound.PlaySound(10002);
                controllerForm.GetGoldUpdate(1);
                collision.gameObject.SetActive(false);
            
                once = true;
               
                GameEntry.TimerComponent.AddOnceTimer(500,()=> { once = false; });
            }
            //玩家触碰到死亡线
            if (collision.gameObject.name == "DeathLine")
            {
                playerEntityData.CurrentHP = 0;
                if (gameObject.tag == "Player")
                {

                    GameEntry.ArchiveData.Data.player.CurrentHP = playerEntityData.CurrentHP;

                    if (GameEntry.ArchiveData.Data.player.CurrentHP <= 0)
                    {
                        GameEntry.ArchiveData.Data.player.CurrentHP = 1;
                    }

                }

                OnDead(null);
            }
        }
        /// <summary>
        /// 设置摄像机跟谁target
        /// </summary>
        private void SetCameraLookPoint()
        {
            Transform point = transform.FindTransform<Transform>("LookPoint");
            Camera.main.GetComponent<CinemachineVirtualCamera>().Follow = point;
            Camera.main.GetComponent<CinemachineVirtualCamera>().LookAt = point; 
        }

        //震动
        private void ScreenShakeFunction() 
        {
            Camera.main.GetComponentInChildren<CinemachineImpulseSource>().GenerateImpulse();
        }


        public void HitAddForce(Entity entity)
        {
            if (!entity) return;

            animHit = true;
            ScreenShakeFunction();


            int direction = entity.transform.position.x > transform.position.x ? -1 : 1;
            float force = 10;

            if (direction==1)
            {
                // entity在右边
                rb.AddForce((Vector3.right + Vector3.up) * force, ForceMode2D.Impulse);
            }
            if (direction == -1)
            {
                // entity在左边
                rb.AddForce((Vector3.left + Vector3.up) * force, ForceMode2D.Impulse);
            }
         

        }

        /// <summary>
        /// 移动输入值
        /// </summary>
        /// <param name="arg"></param>
        private void InputDirection(Vector2 arg)
        {
            inputDirection = arg;
        }


        /// <summary>
        /// 设置动画
        /// </summary>
        private void SetAnimation()
        {
            if (rb.velocity.y <= 0f)
            {
                animJump = false;
                animFall = true;
            }

            if (interactionCheck.isGround)
            {
                animFall = false;
            }

            anim.SetFloat("Movement", animMovement);
            anim.SetBool("Jump", animJump);
            anim.SetBool("Fall", animFall);
            anim.SetBool("Hit", animHit);

            //anim.SetBool("IsAttack", animIsAttack);
            //anim.SetBool("Death", animDeath);
            //anim.SetBool("Skill", animSkill);
        }

        /// <summary>
        /// 移动
        /// </summary>
        private void Movement()
        {
            animMovement = Math.Abs(inputDirection.x);

            if (animMovement<0.25f)
            {
                //预防idle动画移动位置，因为动画是动画树三种根据数值切换
                inputDirection = new Vector2(0,inputDirection.y);
            }

            rb.velocity = new Vector2(inputDirection.x * moveSpeed * 100 * Time.deltaTime, rb.velocity.y);

            if (FaceDirection != 0)
            {
                transform.localScale = new Vector3(FaceDirection, 1, 1);
            }
        }

        /// <summary>
        /// 跳跃
        /// </summary>
        private void Jump()
        {
            if (!interactionCheck.isGround) return;
             
            animJump = true;
            rb.AddForce(transform.up * jumpForce * 10, ForceMode2D.Impulse);
            GameEntry.Sound.PlaySound(10004);

        }
      
        /// <summary>
        /// 攻击
        /// </summary>
        private void AttackFun()
        {
            if (animAttack) return;
          

            if (Utility.Random.GetRandomDouble()<0.8f)
            {
                GameEntry.TimerComponent.AddOnceTimer(200,()=> 
                {
                    areaAttack01.SetActive(true);
                });
                anim.SetTrigger("TriggerAttack01");
                GameEntry.Sound.PlaySound(10000);
            }
            else
            {
                GameEntry.TimerComponent.AddOnceTimer(200, () => 
                { 
                    areaAttack02.SetActive(true); 
                });
                anim.SetTrigger("TriggerAttack02");
                GameEntry.Sound.PlaySound(10001);
            }
        }

        /// <summary>
        /// 隐藏攻击触发对象
        /// </summary>
        public void HideAttackObject()
        {

            areaAttack01.SetActive(false);
            areaAttack02.SetActive(false);
        }     
    }
}
